<?php
namespace app\api_wp_v01\controller;

class ApiWechatProgram {
	
	protected $subscriber_id;		// 订阅者ID
	
	public function __construct() {
		
		// 载入配置文件
		\think\Config::load(CONF_PATH . 'api_wp' . DS . 'config.php');
		
		// 检查执行权限
		$result = $this->checkClientToken($message);
		if(true !== $result){
			$this->returnError(9, $message);
		};
		
	}
	
	/**
	 * 处理Json数据
	 * 处理按规定格式返回的数据
	 */
	protected function disposeJson($error_number, $error_message, $suffix_array = null) {
		
		$array = array(
			'errno' => $error_number,
			'message' => $error_message,
		);
		
		if(null !== $suffix_array){
			$array['data'] = $suffix_array;
		};
		
		return $array;
	}
	
	/**
	 * 返回错误
	 */
	protected function returnError($errno, $message) {
		
		$json = $this->disposeJson($errno, $message);
		$response = \think\Response::create($json, 'json');
		throw new \think\exception\HttpResponseException($response);
	}
	
	/**
	 * 校验用户令牌
	 */
	protected function checkClientToken(&$message) {
		
		// 获取传入的令牌
		$client_token = \think\Request::instance()->header('Client-Token');
		if(null === $client_token){
			$message = '未传入ClientToken，请求拒绝';
			return false;
		};
		
		// 验证令牌信息长度
		$client_token = explode('.', $client_token);
		if(3 !== count($client_token)){
			$message = '传入的ClientToken格式不正确';
			return false;
		};
		
		// 验证名称
		$application_name = \think\Config::get('application_name');
		if($client_token[0] !== ucfirst($application_name)){
			$message = '传入的ClientToken不属于本系统';
			return false;
		};
		
		// 验证令牌标题
		if($client_token[1] !== 'ClientToken'){
			$message = '传入的ClientToken类型不正确';
			return false;
		};
		
		// 解析令牌内容
		$token_content = openssl_decrypt($client_token[2], \think\Config::get('client_token.encrypt_type'), \think\Config::get('client_token.encrypt_key'), \think\Config::get('client_token.encrypt_option'), \think\Config::get('client_token.encrypt_iv'));
		if(false === $token_content){
			$message = '传入的ClientToken内容解析失败';
			return false;
		};
		
		// 验证令牌内容长度
		$token_content = explode('.', $token_content);
		if(2 !== count($token_content)){
			$message = '传入的ClientToken内容格式不正确';
			return false;
		};
		
		// 判断订阅者ID
		if(1 !== preg_match('/^[0-9]{1,10}$/', $token_content[0])){
			$message = '传入的ClientToken内容中订阅者ID不正确';
			return false;
		};
		
		// 定义订阅者数据
		$this->subscriber_id = intval($token_content[0]);
		return true;
		
	}
	
	/**
	 * 初始化Redis
	 */
	protected function getRedis() {
		
		if(!class_exists('Redis')){
			$this->returnError(9, '当前不支持Redis');
		};
		
		\think\Config::load(CONF_PATH . 'redis.php');
		$redis_service = \think\Config::get('redis_service');
		if(!is_array($redis_service)){
			$this->returnError(9, '当前Redis配置参数有误，请联系管理员');
		};
		
		$redis = new \Redis();
		if(is_integer($redis_service['port'])){
			$result = $redis->connect($redis_service['host'], $redis_service['port']);
		}else{
			$result = $redis->connect($redis_service['host']);
		};
		if(true !== $result){
			$this->returnError(9, '连接Redis服务失败，请联系管理员');
		};
		
		if(is_string($redis_service['auth'])){
			$result = $redis->auth($redis_service['auth']);
			if(true !== $result){
				$this->returnError(9, '认证Redis服务失败，请联系管理员');
			};
		};
		
		if(is_integer($redis_service['select'])){
			$result = $redis->select($redis_service['select']);
			if(true !== $result){
				$this->returnError(9, '选择Redis服务库失败，请联系管理员');
			};
		};
		
		return $redis;
	}
	
	/**
	 * 发送请求
     * @access protected
	 * @param  string $target_url 目标Url地址
	 * @param  array  $data_array  发送的数据
	 * @return mix
	 */
	protected function sendRequest($target_url, $data_array = null) {
		
		// 初始化连接
		$curl_link = curl_init();
		curl_setopt($curl_link, CURLOPT_URL, $target_url);
		curl_setopt($curl_link, CURLOPT_RETURNTRANSFER, 1 );
		
		// 判断是否为HTTPS链接
		if(false !== stripos($target_url, 'https://')){		// 判断是否使用SSL
			curl_setopt($curl_link, CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($curl_link, CURLOPT_SSL_VERIFYHOST, false);
			curl_setopt($curl_link, CURLOPT_SSLVERSION, 1); // CURL_SSLVERSION_TLSv1
		};
		
		// 是否为POST请求
		if(is_array($data_array)){
			curl_setopt($curl_link, CURLOPT_POST, true);
			curl_setopt($curl_link, CURLOPT_POSTFIELDS, json_encode($data_array, JSON_UNESCAPED_UNICODE));
		};
		
		// 发送请求并判断HTTP状态码
		$response = curl_exec($curl_link);
		$http_status = curl_getinfo($curl_link);
		if(200 !== $http_status['http_code']){
			return '请求远程服务失败';
		};
		
		// 解析返回数据
		$response = json_decode($response, true);
		if(false === $response || null === $response){
			return '解析远程服务返回数据失败';
		};
		
		return $response;
	}
}